package ia04.agent.time;

import ia04.util.StreamToString;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.impl.client.DefaultHttpClient;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import jade.core.AID;
import jade.core.Agent;
import jade.core.behaviours.TickerBehaviour;
import jade.lang.acl.ACLMessage;

public class BehavUpdateTime extends TickerBehaviour {

	private HttpGet httpget;

	// For Proxy
	private DefaultHttpClient httpclient;
	private HttpHost proxy;

	final static long period = 300000; // 5 min = 5*60*1000 ms
	final String serviceRestUrl = "http://json-time.appspot.com/time.json?tz=Europe/Paris";
	final boolean bUseProxy = false;

	public BehavUpdateTime(Agent a)
	{
		super(a, period);
		
		// Create client
		httpclient = new DefaultHttpClient();
		
		if(bUseProxy)
		{
			// Define proxy
			proxy = new HttpHost("proxyweb.utc.fr", 3128);
			httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
		}
		
		// Prepare a request object
		httpget = new HttpGet(serviceRestUrl);

		updateNeeded();
	}

	@Override
	public void onTick()
	{
		updateNeeded();
	}
	
	private void updateNeeded()
	{
		// Update weather
		// Execute the request
		try {
			String xmlString = "";
			HttpResponse response = httpclient.execute(httpget);
			
			// Examine the response status
			System.out.println(response.getStatusLine());
			// Get hold of the response entity
			HttpEntity entity = response.getEntity();
			// If the response does not enclose an entity, there is no need to worry about connection release
			if (entity != null)
			{
				InputStream instream = entity.getContent();
				xmlString = StreamToString.convertStreamToString(instream);
			}
			if(!xmlString.isEmpty())
			{
				if(updateTime(decodeJsonTime(xmlString)))
				{
					broadcastTime();
				}
			}
		} catch (ClientProtocolException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}		
	}

	private boolean updateTime(String newTime)
	{
		System.out.println("BEFORE UPDATE: " + ((AgentTime)myAgent).getTime() + " & CURRENT TIME: " + newTime);
		
		if(!newTime.isEmpty() && !newTime.equals(((AgentTime)myAgent).getTime()))
		{
			((AgentTime)myAgent).setTime(newTime);
			
			System.out.println("AFTER UPDATE: " + ((AgentTime)myAgent).getTime());
			return true;
		}

		return false;
	}
	
	private void broadcastTime()
	{
		// Get subscribers
		ArrayList<AID> subscribedAgents = ((AgentTime)myAgent).getSubscribedAgents();
		
		if(!subscribedAgents.isEmpty()) return;

		// Build answer
		String answer = ((AgentTime)myAgent).getTime();
		
		// Build message
		ACLMessage msg = new ACLMessage(ACLMessage.INFORM);
		msg.setContent(answer);
		
		for(int i = 0; i < subscribedAgents.size(); ++i)
		{
			msg.addReceiver(subscribedAgents.get(i));
		}
		
		// Send message
		myAgent.send(msg);
	}

	public String decodeJsonTime(String jsonStr)
	{
		ObjectMapper m = new ObjectMapper();
		String time = "";
		int hour = -1;
		JsonNode rootNode;
		try {
			rootNode = m.readValue(jsonStr, JsonNode.class);
			//time = rootNode.path("hour").getValueAsText() + ":" + rootNode.path("minute").getValueAsText();
			hour = rootNode.path("hour").getValueAsInt();
			if(hour > -1 && hour < 25)
			{
				if(hour > 21 || hour < 6)
					time = "Nuit";
				else
					time = "Jour";
			}
		} catch (JsonParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (JsonMappingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return time;
	}
}
